package main

import (
	"encoding/json"
	"fmt"
	"io"
	"reflect"
)

type person struct {
	Name string
	Age  int64
}

func (p person) String() string {
	return fmt.Sprintf("Name is %s,Age is %d", p.Name, p.Age)
}

func main() {
	n := 3
	nv := reflect.ValueOf(n) // 3
	nt := reflect.TypeOf(n)  // int
	fmt.Println(nv, nt)

	i := 5
	iv := reflect.ValueOf(i)
	i1 := iv.Interface().(int)
	fmt.Println(i1)

	npv := reflect.ValueOf(&n)
	npv.Elem().SetInt(10)
	fmt.Println(n)

	s := person{"Tom", 18}
	spv := reflect.ValueOf(&s)
	spv.Elem().Field(0).SetString("张三")
	fmt.Println(s)

	ppv := reflect.ValueOf(&s)
	fmt.Println(ppv.Kind())
	pv := reflect.ValueOf(s)
	fmt.Println(pv.Kind())

	pt := reflect.TypeOf(s)
	//遍历person的字段
	for i := 0; i < pt.NumField(); i++ {
		fmt.Println("字段：", pt.Field(i).Name)
	}
	//遍历person的方法
	for i := 0; i < pt.NumMethod(); i++ {
		fmt.Println("方法：", pt.Method(i).Name)
	}

	spt := reflect.TypeOf(s)
	stringerType := reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
	writerType := reflect.TypeOf((*io.Writer)(nil)).Elem()
	fmt.Println("是否实现了fmt.Stringer：", spt.Implements(stringerType))
	fmt.Println("是否实现了io.Writer：", spt.Implements(writerType))

	// struct to json
	jsonB, err := json.Marshal(s)
	if err == nil {
		fmt.Println(string(jsonB)) // {"Name":"张三","Age":18}
	}

	// json to struct
	jsonStr := `{"Name":"张三","Age":18}`
	json.Unmarshal([]byte(jsonStr), &s) // Name is 张三,Age is 18
	fmt.Println(s)
}
